package com.qijian.common.utils.sync;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.qijian.common.core.redis.RedisCache;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.StringUtils;
import lombok.SneakyThrows;
import org.apache.commons.collections.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author qijian
 */
@Component
public class KingdeeSynUtils {

    private static RedisCache redisCache;

    public static final String POST_K3CloudURL = "http://kd.zjavim.com/k3cloud/";

    private final static Integer loginTimeOutSecond = 5;

    private final static String userTokenKey = "KingDee:Login:UserToken";
    private final static String cookieKey = "KingDee:Login:Cookie";

    //token
    private static String userToken = null;
    // Cookie ֵ
    private static String CookieVal = null;
    //请求参数
    private static final JSONObject jObj = new JSONObject();
    // 登录金蝶
    private static String dbId = "";
    //    private static String dbId = "607502a416626d";
    private static final String uid = "";
    private static final String pwd = "";
    private static final int lang = 2052; // 中文
    //    public static boolean open = false;
    public static boolean open = true;

    public static Integer buffered_sz_default = 8192;
    public static Integer buffered_sz = buffered_sz_default;

    @Value("${kingdee.dbId}")
    public void setDbId(String dbId) {
        KingdeeSynUtils.dbId = dbId;
    }

    @Value("${kingdee.open}")
    public void setOpen(Boolean open) {
        KingdeeSynUtils.open = open;
    }

    @Autowired
    public void setRedisCache(RedisCache redisCache) {
        KingdeeSynUtils.redisCache = redisCache;
    }

    private static final Map<String, String> map = new HashMap<>();

    static {
        map.put("Save",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc");
        map.put("View",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.View.common.kdsvc");
        map.put("Submit",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit.common.kdsvc");
        map.put("Audit",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Audit.common.kdsvc");
        map.put("UnAudit",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.UnAudit.common.kdsvc");
        map.put("StatusConvert",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.StatusConvert.common.kdsvc");
        map.put("ExecuteBillQuery",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc");
        map.put("Download", "FileUpLoadServices/download.aspx");
        map.put("Delete",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Delete.common.kdsvc");
        map.put("CancelAssign",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.CancelAssign.common.kdsvc");
        map.put("GetSysReportData",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.GetSysReportData.common.kdsvc");
        map.put("Draft",
                "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Draft.common.kdsvc");


        jObj.set("OrderString", "");
        jObj.set("TopRowCount", 0);
        jObj.set("StartRow", 0);
        jObj.set("Limit", 0);
    }

    // HttpURLConnection
    private static HttpURLConnection initUrlConn(String url, JSONArray paras)
            throws Exception {
        URL postUrl = new URL(POST_K3CloudURL.concat(url));
        HttpURLConnection connection = (HttpURLConnection) postUrl
                .openConnection();
        if (CookieVal != null) {
            connection.setRequestProperty("Cookie", CookieVal);
        }
        if (!connection.getDoOutput()) {
            connection.setDoOutput(true);
        }
        connection.setRequestMethod("POST");
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setRequestProperty("Content-Type", "application/json");
        DataOutputStream out = new DataOutputStream(
                connection.getOutputStream());

        UUID uuid = UUID.randomUUID();
        int hashCode = uuid.toString().hashCode();

        JSONObject jObj = new JSONObject();

        jObj.set("format", 1);
        jObj.set("useragent", "ApiClient");
        jObj.set("rid", hashCode);
        jObj.set("parameters", chinaToUnicode(paras.toString()));
        jObj.set("timestamp", new Date().toString());
        jObj.set("v", "1.0");

        out.writeBytes(jObj.toString());
        out.flush();
        out.close();
        return connection;
    }

    // Login
    protected static boolean Login() throws Exception {
        if (redisCache != null) {
            userToken = redisCache.getCacheObject(userTokenKey);
            CookieVal = redisCache.getCacheObject(cookieKey);
            if (CookieVal != null && userToken != null) {
                //如果在过期时间内能够成功取到，说明2次调用的时间在过期时间之内，则重新覆盖过期时间
                redisCache.expire(cookieKey, loginTimeOutSecond, TimeUnit.SECONDS);
                redisCache.expire(userTokenKey, loginTimeOutSecond, TimeUnit.SECONDS);
                return true;
            }
        }
        boolean bResult;
        String sUrl = "Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc";

        JSONArray jParas = new JSONArray();
        jParas.add(KingdeeSynUtils.dbId);// 帐套Id
        jParas.add(KingdeeSynUtils.uid);// 用户名
        jParas.add(KingdeeSynUtils.pwd);// 密码
        jParas.add(KingdeeSynUtils.lang);// 语言

        HttpURLConnection connection = initUrlConn(sUrl, jParas);
        // 获取Cookie
        String key;
        for (int i = 1; (key = connection.getHeaderFieldKey(i)) != null; i++) {
            if ("Set-Cookie".equalsIgnoreCase(key)) {
                String tempCookieVal = connection.getHeaderField(i);
                if (tempCookieVal.startsWith("kdservice-sessionid")) {
                    CookieVal = tempCookieVal;
                    if (redisCache != null) {
                        redisCache.setCacheObject(cookieKey, CookieVal, loginTimeOutSecond, TimeUnit.SECONDS);
                    }
                    break;
                }
            }
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuilder ret = new StringBuilder();
        while (reader.ready()) { // 当客户端主动中断连接时此处会返回-1
            ret.append(reader.readLine()); // 在最后一次读取，len会小于数组大小，此处设置len避免末尾无效数据
        }
        bResult = ret.indexOf("\"LoginResultType\":1") > -1;
        if (bResult) {
            userToken = new JSONObject(ret).getJSONObject("Context").getStr("UserToken");
            if (redisCache != null) {
                redisCache.setCacheObject(userTokenKey, userToken, loginTimeOutSecond, TimeUnit.SECONDS);
            }
        }
        reader.close();
        connection.disconnect();
        return bResult;
    }

    // Save
    public static String Save(String formId, String content) throws Exception {
        return open ? Invoke("Save", formId, content) : "";
    }

    public static String Draft(String formId, String content) throws Exception {
        return open ? Invoke("Draft",formId, content) : "";
    }


    //    // View
//    private static String View(String formId, String content) throws Exception {
//        return Invoke("View", formId, content);
//    }
//
//    // Submit
    public static String Submit(String formId, String content) throws Exception {
        return Invoke("Submit", formId, content);
    }

    //
//    // Audit
    public static String Audit(String formId, String content) throws Exception {
        return Invoke("Audit", formId, content);
    }

    //删除
    public static String Delete(String formId, String content) throws Exception {
        return Invoke("Delete", formId, content);
    }

    public static String CancelAssign(String formId, String content) throws Exception {
        return Invoke("CancelAssign", formId, content);
    }
//
//    // UnAudit
//    private static String UnAudit(String formId, String content) throws Exception {
//        return Invoke("UnAudit", formId, content);
//    }
//
//    // StatusConvert
//    private static String StatusConvert(String formId, String content)
//            throws Exception {
//        return Invoke("StatusConvert", formId, content);
//    }

    // ExecuteBillQuery
    private static String ExecuteBillQuery(String content) throws Exception {
        return open ? InvokeQuery(content) : "";
    }

    private static String Invoke(String type, String formId, String content)
            throws Exception {
        String sResult = "";
        if (Login()) {
            String sUrl = map.get(type);
            JSONArray jParas = new JSONArray();
            jParas.add(formId);
            jParas.add(content);

            HttpURLConnection connectionInvoke = initUrlConn(sUrl, jParas);

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    connectionInvoke.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                sResult = new String(line.getBytes(), StandardCharsets.UTF_8);
            }
            reader.close();

            connectionInvoke.disconnect();
        }
        return sResult;
    }




    private static String InvokeQuery(String content)
            throws Exception {

        String sUrl = map.get("ExecuteBillQuery");
        JSONArray jParas = new JSONArray();
        jParas.add(content);

        HttpURLConnection connectionInvoke = initUrlConn(sUrl, jParas);


        BufferedReader reader = new BufferedReader(new InputStreamReader(connectionInvoke.getInputStream()), buffered_sz);
        StringBuilder ret = new StringBuilder();
        if (reader.ready())
            reader.lines().forEach(ret::append);
//        while (reader.ready()) { // 当客户端主动中断连接时此处会返回-1
//            ret.append(reader.readLine());
//            ret.append((char) reader.read()); // 在最后一次读取，len会小于数组大小，此处设置len避免末尾无效数据
//        }
        reader.close();
        connectionInvoke.disconnect();
        return ret.toString();
    }

    /**
     * 把中文转成Unicode码
     */
    public static String chinaToUnicode(String str) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            int chr1 = str.charAt(i);
            if (chr1 >= 19968) {
                sb.append("\\u").append(Integer.toHexString(chr1));
            } else {
                sb.append(str.charAt(i));
            }
        }
        return sb.toString();
    }

    protected static String callData(long start, String formId, String fieldKeys, String filterString) throws
            Exception {
        jObj.set("FormId", formId);
        jObj.set("FieldKeys", fieldKeys);
        jObj.set("FilterString", filterString);
        jObj.set("StartRow", start == 0 ? 1 : start);
        jObj.set("Limit", start == 0 ? 0 : 9999);
        String content = jObj.toString();

        return ExecuteBillQuery(content); // 表单数据查询
    }

    protected static String callDataNew(long start,long size, String formId, String fieldKeys, String filterString) throws
            Exception {
        jObj.set("FormId", formId);
        jObj.set("FieldKeys", fieldKeys);
        jObj.set("FilterString", filterString);
        jObj.set("StartRow", start == 0 ? 1 : start);
        jObj.set("Limit", size == 0 ? 0 : size);
        String content = jObj.toString();

        return ExecuteBillQuery(content); // 表单数据查询
    }

    @SneakyThrows
    public String downloadPath(String fileId) {
        assert fileId != null;
        if (!Login())
            throw new RuntimeException();
        String basePath = POST_K3CloudURL + map.get("Download");
        return basePath + String.format("?fileId=%s&dbId=%s&t=%s&token=%s", fileId, dbId, new Date().getTime(), userToken);
    }

    public static JSONArray getDept(long start) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "BD_Department";
                // 部门编号，部门名称
                String fieldKeys = "FDEPTID,FName,FUseOrgId,FNumber";
                String result = callData(start, formId, fieldKeys, null);
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("部门： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getJob(long start) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "HR_ORG_HRPOST"; //
                // 岗位编号，岗位名称
                String fieldKeys = "FPOSTID,FName,FUseOrgId,FNumber,FDept.FNumber"; //
                String filterstring = "FUseOrgId = 100121 ";
                String result = callData(start, formId, fieldKeys, filterstring);
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("岗位： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getProject(String lastDate, String projectNo) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "k441ff31b955046bab1f7c2b819d60501"; //
                // 项目号，项目名称，机台号
                String fieldKeys = "F_ora_Text2,F_ora_Text1,F_ora_Text3,FCreateDate,FBILLSTATUS,F_BEQ_BASE2" +
                        ",FCreatorId.FName,FModifierId.FName,FModifyDate,FID,F_BEQ_BASE2.FMOBILE,F_BEQ_Integer,F_BEQ_Base1,F_BEQ_BaseProperty";
                String filterString = "";
                String param1 = "F_ora_Text2 = '#projectNo'";
                String param2 = "FModifyDate > '#lastDate'";
                if (StringUtils.isNotBlank(lastDate)) {
                    filterString = param2.replace("#lastDate", lastDate);
                }
                if (StringUtils.isNotBlank(projectNo)) {
                    filterString += StringUtils.isNotBlank(filterString) ? " and " : "";
                    filterString += param1.replace("#projectNo", projectNo);
                }
                String result = callData(0, formId, fieldKeys, filterString);
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("项目： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getItem(String lastDate) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "BD_MATERIAL"; //
                //
                String fieldKeys = "FNUMBER,FMnemonicCode,FNAME,FERPCLSID,FBASEUNITID.FNumber,FBASEUNITID.FName,FMATERIALGROUP.FName,FMATERIALGROUP.FNumber," +
                        "FForbidStatus,FForbidderId.FName,FForbidDate,FDOCUMENTSTATUS,FApproverId.FName,FApproveDate,FDescription," +
                        "FCreatorID.FName,FModifierID.FName,FCreateDate,FModifyDate,FMATERIALID"; //
                String filterString = "FUseOrgId = 100121 and FModifyDate > '#lastDate'";//""FModifyDate > '" + DateUtil.localDateTimeFormatyMdHms(localDateTime) + "'";
                String result = callData(0, formId, fieldKeys, filterString.replace("#lastDate", lastDate));
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("物料： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getItemById(String id) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "BD_MATERIAL"; //
                //
                String fieldKeys = "FNUMBER,FMnemonicCode,FNAME,FERPCLSID,FBASEUNITID.FNumber,FBASEUNITID.FName,FMATERIALGROUP.FName,FMATERIALGROUP.FNumber," +
                        "FForbidStatus,FForbidderId.FName,FForbidDate,FDOCUMENTSTATUS,FApproverId.FName,FApproveDate,FDescription," +
                        "FCreatorID.FName,FModifierID.FName,FCreateDate,FModifyDate,FMATERIALID,FPickStockId,FPickStockId.FNumber"; //
                String filterString = "FUseOrgId = 100121 and FMATERIALID = #FMATERIALID";
                String result = callData(0, formId, fieldKeys, filterString.replace("#FMATERIALID", id));
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("物料： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getItemByNumber(String number) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "BD_MATERIAL"; //
                //
                String fieldKeys = "FNUMBER,FMnemonicCode,FNAME,FERPCLSID,FBASEUNITID.FNumber,FBASEUNITID.FName,FMATERIALGROUP,FMATERIALGROUP.FName," +
                        "FForbidStatus,FForbidderId.FName,FForbidDate,FDOCUMENTSTATUS,FApproverId.FName,FApproveDate,FDescription," +
                        "FCreatorID.FName,FModifierID.FName,FCreateDate,FModifyDate,FMATERIALID,F_ORA_figure,F_ORA_piece," +
                        "FGROSSWEIGHT,FNETWEIGHT,FLENGTH,FWIDTH,FHEIGHT,FVOLUME,F_ora_Combo,F_ora_Text,FCreateDate,FSpecification,F_ora_Qty,F_ora_hole"; //
                String filterString = "FNUMBER = '#FNUMBER'";//""FModifyDate > '" + DateUtil.localDateTimeFormatyMdHms(localDateTime) + "'";
                String result = callData(0, formId, fieldKeys, filterString.replace("#FNUMBER", number));
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("物料： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getWork(String FBomId) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "PRD_MO"; //
                //
                String fieldKeys = "FID,FBillNo,FDate,FPPBOMType,FMaterialId,FMaterialId.FNumber,FMaterialId.FName,FMaterialId.FPLMMaterialId,FMaterialId.F_ORA_figure,FMaterialId.F_ORA_piece,FQty,FUnitId.FNumber,,FUnitId.FName,FPlanStartDate,FPlanFinishDate,FMtoNo,FProjectNo,FBomId,FApproverId.FName,FApproveDate"; //
                String filterString = "FPrdOrgId = 100121 and FMtoNo is not null and TRIM(FMtoNo) <> '' and FMaterialId in (#FBomId)";
                String result = callData(0, formId, fieldKeys, filterString.replace("#FBomId", FBomId));
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("工单： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }

    public static JSONArray getBom(int start) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "ENG_BOM"; //
                //
                String fieldKeys = "FID,FDocumentStatus,FForbidStatus,FName,FMATERIALID,FMATERIALID.FNumber,FMATERIALID.FName,FMATERIALID.FPLMMaterialId," +
                        "FMATERIALID.F_ORA_figure,FMATERIALID.F_ORA_piece,FMATERIALID.FGROSSWEIGHT,FMATERIALID.FNETWEIGHT ,FUNITID.FNumber,FUNITID.FName," +
                        "FGroup,FGroup.FName,FMATERIALIDCHILD,FMATERIALIDCHILD.FNumber,FMATERIALIDCHILD.FName,Fjianhao,Ftuhao,FCHILDITEMPROPERTY," +
                        "FCHILDUNITID.FNumber,FCHILDUNITID.FName,FMATERIALIDCHILD.FGROSSWEIGHT,FMATERIALIDCHILD.FNETWEIGHT,FNumber,FBOMID,FNUMERATOR," +
                        "FAUXPROPID.FF100006.fnumber,FAUXPROPID.FF100006.fdatavalue,FApproverId.FName,FApproveDate,FMATERIALIDCHILD.FMaterialGroup," +
                        "FMATERIALIDCHILD.FMnemonicCode,FNumber,FMATERIALID.FMaterialGroup,FReplaceGroup,FMATERIALIDCHILD.F_ORA_figure," +
                        "FMATERIALIDCHILD.F_ORA_piece,FMATERIALIDCHILD.F_ora_Combo,FMATERIALIDCHILD.FLENGTH,FMATERIALIDCHILD.FWIDTH," +
                        "FMATERIALIDCHILD.FHEIGHT,FMATERIALIDCHILD.FVOLUME,FMATERIALIDCHILD.F_ora_Text,FISDEFAULT"; //
                String filterString = "FDocumentStatus = 'C' and FForbidStatus = 'A' and FUseOrgId = 100121";//FMATERIALID in (1134366,1134411,1134412,1134413)
                String result = callData(start, formId, fieldKeys, filterString);
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    System.out.println("BOM： " + jsonArray.size());
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
        return jsonArray;
    }


    public static void getBom(String fid, List<JSONArray> datas) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (Login()) {
                String formId = "ENG_BOM"; //
                //
                String fieldKeys = "FID,FDocumentStatus,FForbidStatus,FName,FMATERIALID,FMATERIALID.FNumber,FMATERIALID.FName,FMATERIALID.FPLMMaterialId," +
                        "FMATERIALID.F_ORA_figure,FMATERIALID.F_ORA_piece,FMATERIALID.FGROSSWEIGHT,FMATERIALID.FNETWEIGHT ,FUNITID.FNumber,FUNITID.FName," +
                        "FGroup,FGroup.FName,FMATERIALIDCHILD,FMATERIALIDCHILD.FNumber,FMATERIALIDCHILD.FName,Fjianhao,Ftuhao,FCHILDITEMPROPERTY," +
                        "FCHILDUNITID.FNumber,FCHILDUNITID.FName,FMATERIALIDCHILD.FGROSSWEIGHT,FMATERIALIDCHILD.FNETWEIGHT,FNumber,FBOMID,FNUMERATOR," +
                        "FAUXPROPID.FF100006.fnumber,FAUXPROPID.FF100006.fdatavalue,FApproverId.FName,FApproveDate,FMATERIALIDCHILD.FMaterialGroup," +
                        "FMATERIALIDCHILD.FMnemonicCode,FNumber,FMATERIALID.FMaterialGroup,FReplaceGroup,FMATERIALIDCHILD.F_ORA_figure," +
                        "FMATERIALIDCHILD.F_ORA_piece,FMATERIALIDCHILD.F_ora_Combo,FMATERIALIDCHILD.FLENGTH,FMATERIALIDCHILD.FWIDTH," +
                        "FMATERIALIDCHILD.FHEIGHT,FMATERIALIDCHILD.FVOLUME,FMATERIALIDCHILD.F_ora_Text,FISDEFAULT,FCreateDate,FApproveDate,FMATERIALIDCHILD.FSpecification,FCreatorId.FName,FApproverId.FName,FMATERIALIDCHILD.F_ora_Qty" +
                        ",FAUXPROPID.FF100001.fdatavalue,FAUXPROPID.FF100002.fdatavalue,FMATERIALIDCHILD.F_ora_hole,FCreatorId.FUserAccount"; //
                String filterString = "FMATERIALID in (#FMATERIALID) and FDocumentStatus = 'C' and FForbidStatus = 'A'";//FMATERIALID in (1134366,1134411,1134412,1134413)
                String result = callData(0, formId, fieldKeys, filterString.replace("#FMATERIALID", fid));
                if (StringUtils.isNotBlank(result)) {
                    jsonArray = JSONUtil.parseArray(result);
                    Map<String, JSONArray> repeatCount = new LinkedHashMap<>(jsonArray.size());
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONArray data = jsonArray.getJSONArray(i);
                        String nowKey = data.getStr(17);
                        JSONArray old = repeatCount.get(nowKey);
                        if (old != null) {
                            String oldVersion = repeatCount.get(nowKey).getStr(26).split("V")[1];
                            String newVersion = data.getStr(26).split("V")[1];
                            int chayi = StringUtils.compareVersion(oldVersion, newVersion);
                            if (chayi != -1) {
                                data = repeatCount.get(nowKey);
                            }
                        }
                        repeatCount.put(nowKey, data);
                    }
                    for (String key : repeatCount.keySet()) {
                        JSONArray data = repeatCount.get(key);
                        String type = data.getStr(21);
                        datas.add(data);
                        if ("2".equals(type)) {
                            getBom(data.getStr(16), datas);
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("登录异常");
        }
    }

    public static JSONArray getBomByNumber(String number) {
        JSONArray bomArray = getBom(0);
        Map<Integer, JSONArray> dataMap = new HashMap<>(bomArray.size());
        Map<Integer, List<JSONArray>> listMap = new HashMap<>(bomArray.size());
        for (int i = 0; i < bomArray.size(); i++) {
            dataMap.put(bomArray.getJSONArray(i).getInt(16), bomArray.getJSONArray(i));
            Integer key = bomArray.getJSONArray(i).getInt(4);
            List<JSONArray> list = listMap.get(key);
            JSONArray data = bomArray.getJSONArray(i);
            boolean isCheck = true;
            if (list == null) {
                list = new ArrayList<>(16);
                listMap.put(key, list);
            } else {
                for (int j = 0; j < list.size(); j++) {
                    if (list.get(j).getStr(17).equals(data.getStr(17))) {
                        if (data.getStr(17).equals("EP3E2ZCB010101001")) {
                            System.out.println("test");
                        }
                        isCheck = false;
                        String[] oldVersion = list.get(j).getStr(26).split("V");
                        String[] newVersion = data.getStr(26).split("V");
//                        System.out.println("oldVersion: " + JSON.toJSONString(oldVersion) + "    newVersion: " + JSON.toJSONString(newVersion));
                        if (oldVersion.length > 1 && newVersion.length > 1) {
                            if (StringUtils.compareVersion(oldVersion[1], newVersion[1]) == -1) {
                                list.set(j, data);
                            }
                        }
                        break;
                    }
                }
            }
            if (isCheck) {
                list.add(data);
            }
        }
        Map<String, JSONObject> parent = new HashMap<>(16);
        dataMap.forEach((key, value) -> {
            if (dataMap.get(value.getInt(4)) == null && number.equals(value.getStr(5))) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.set("fid", value.getStr(4));
                jsonObject.set("number", value.getStr(5));
                jsonObject.set("name", value.getStr(6));
                jsonObject.set("drawingno", value.getStr(8));
                jsonObject.set("partno", value.getStr(9));
                jsonObject.set("grossweight", value.getBigDecimal(10));
                jsonObject.set("netweight", value.getBigDecimal(11));
                jsonObject.set("unitNumber", value.getStr(12));
                jsonObject.set("unitName", value.getStr(13));
                jsonObject.set("approvalBy", value.getStr(31));
                jsonObject.set("version", value.getStr(35));
                jsonObject.set("groupName", value.getStr(36));
                jsonObject.set("oraCombo", value.getStr(40));
                JSONObject spec = new JSONObject();
                spec.set("FLENGTH", value.getStr(41));
                spec.set("FWIDTH", value.getStr(42));
                spec.set("FHEIGHT", value.getStr(43));
                spec.set("FVOLUME", value.getStr(44));
                jsonObject.set("itemSpec", spec.toString());
                jsonObject.set("itemMaterial", value.getStr(45));
                parent.put(value.getStr(5), jsonObject);
            }
        });
        Map<String, Map<String, List<JSONArray>>> data = new HashMap<>(parent.size());
        for (String key : parent.keySet()) {
            data.put(key, new HashMap<>(15));
            treeData(key, parent.get(key).getInt("fid"), listMap, data, 1);
        }
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(parent.get(number));
        jsonArray.add(data.get(number));
        return jsonArray;
    }


    public static void treeData(String key, Integer
            parentKey, Map<Integer, List<JSONArray>> dataMap, Map<String, Map<String, List<JSONArray>>> parent,
                                int num) {
        List<JSONArray> list = dataMap.get(parentKey);
        if (list != null) {
            for (JSONArray objects : list) {
                String type = objects.getStr(21);
                if ("2".equals(type)) {
                    treeData(key, objects.getInt(16), dataMap, parent, num + 1);
                }
            }
            Map<String, List<JSONArray>> levelMap = parent.get(key);
            if (levelMap == null) {
                levelMap = new HashMap<>(8);
                levelMap.put(num + "", list);
            } else {
                List<JSONArray> jsonArrays = levelMap.get(num + "");
                if (jsonArrays != null) {
                    jsonArrays.addAll(list);
                } else {
                    jsonArrays = list;
                }
                levelMap.put(num + "", jsonArrays);
            }
        }
    }

    /**
     * 缩略简化项目机台号
     *
     * @param projectMachineNo
     * @return
     */
    @SuppressWarnings({"unchecked"})
    public static String simpleProjectMachineNo(String[] projectMachineNo) {
        Map<String, List<String>> resultMap = new HashMap<>();

        Map<String, List<String>> collect = Arrays.stream(projectMachineNo)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toMap(s -> StringUtils.substringBefore(s, '(')
                        , s -> Lists.newArrayList(StringUtils.substringBetween(s, "(", "#)"))
                        , ListUtils::union));

        collect.keySet().forEach(k -> {
            List<String> strMachine = collect.get(k).stream().filter(s -> !org.apache.commons.lang3.StringUtils.isNumeric(s)).collect(Collectors.toList());
            collect.get(k).removeAll(strMachine);
            resultMap.computeIfAbsent(k, a -> strMachine.stream().map(s -> s + "#").collect(Collectors.toList()));
        });

        collect.forEach((c, v) -> {
            List<Integer> machineList = v.stream().map(Integer::parseInt).sorted().collect(Collectors.toList());
            int max = machineList.size();
            for (int i = 0; i < max; ) {
                int endIndex = i + 1;
                Integer start = machineList.get(i);
                Integer sufixx = null;
                for (; endIndex < max; endIndex++) {
                    Integer end = machineList.get(endIndex);
                    if (end != start + endIndex - i)
                        break;
                    else sufixx = end;
                }
                List<String> machineNo = resultMap.computeIfAbsent(c, k -> new ArrayList<>());
                if (sufixx != null)
                    machineNo.add(String.format("%s-%s#", machineList.get(i), sufixx));
                else
                    machineNo.add(String.valueOf(machineList.get(i)) + "#");
                i = endIndex;
            }
        });

        List<String> r = resultMap.keySet().stream().map(k -> resultMap.get(k).stream().map(s -> String.format("%s(%s)", k, s))
                .collect(Collectors.toList())).flatMap(Collection::stream).collect(Collectors.toList());

        return String.join(",", r);
    }

    //    public static void main(String[] args) {
//        try {
//            String[] fieldKeys = "FNUMBER,FMnemonicCode,FNAME,FERPCLSID,FBASEUNITID.FNumber,FBASEUNITID.FName,FMATERIALGROUP.FName,FMATERIALGROUP.FNumber,FForbidStatus,FForbidderId.FName,FForbidDate,FDOCUMENTSTATUS,FApproverId.FName,FApproveDate,FDescription,FCreatorID.FName,FModifierID.FName,FCreateDate,FModifyDate,FMATERIALID,F_ORA_figure,F_ORA_piece,FGROSSWEIGHT,FNETWEIGHT,FLENGTH,FWIDTH,FHEIGHT,FVOLUME,F_ora_Combo,F_ora_Text,FCreateDate,FSpecification,F_ora_Qty,F_ora_hole".split(","); //
//            JSONArray jsonArray = getItemByNumber("GZ21343");
//            for (int i = 0; i < jsonArray.getJSONArray(0).size(); i++) {
//                System.out.println(i + ": " + fieldKeys[i] + ": " + jsonArray.getJSONArray(0).get(i));
//            }
////            JSONArray jsonArray = getWork("817271,1134366,1134368,1134373,1134374,1134375,1134396,1134401,1134403,1134404,1134405,1134406,1134410,1134411,1134412,1134413,1164128,1251020,1251024,1251025,1251026,1251027,1251028,1251029");
////            JSONArray jsonArray = getProject(null, "P036");
////            JSONArray jsonArray = getItemById("308107");
////            JSONArray jsonArray = getJob(0);
//            List<JSONArray> datas = new ArrayList<>(16);
//            getBom(jsonArray.getJSONArray(0).getStr(19), datas);
//            for (JSONArray data : datas) {
//                System.out.println(data);
//            }
////            String userName = "张天翼5", phone = "13012340014", deptNumber = "BM000027", jobNumber = "GW000328", userOrgNumber = "10003";
////            String result = addStaff(userName, phone, deptNumber, jobNumber, new Date(), userOrgNumber);
////            System.out.println(result);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

    public static Map<String, Object>  handleResult(String result) {
        Map<String, Object> map = new HashMap<>();
        cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(result);
        cn.hutool.json.JSONObject statusJson = (cn.hutool.json.JSONObject) jsonObject.get("Result");
        cn.hutool.json.JSONObject resultJson = (cn.hutool.json.JSONObject) statusJson.get("ResponseStatus");
        Boolean isSuccess = (Boolean) resultJson.get("IsSuccess");
        if (isSuccess) {
            Integer id = (Integer) statusJson.get("Id");
            String number = (String) statusJson.get("Number");
            map.put("id", id);
            map.put("number", number);
            return map;
        } else {
            Object errors = resultJson.get("Errors");
            throw new ServiceException("金蝶错误信息：" + errors);
        }

    }
    public static void main(String[] args) {
//        getProject(null, "GZ22029 船体罩镗铣装夹工装");
        List<JSONArray> arr = new ArrayList<>();
        getBom("1665548", arr);
        System.out.println(arr);
    }
}
